<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
</head>

<body>
    <script>
        //一、概念题 25'
        //1.在dom操作中获取节点的方法，5种，每个一分
        // document.querySelector() document.querySelectorAll() document.getElementById() document.getElementsByClassName() document.getElementsByTagName()
        //2.添加节点的两种方法(2') NodeList和HTMLCollection的区别(3')
        // appendChild() insertBefore() NodeList会获取所有节点信息 HTMLCollection只能获取标签节点信息
        //3.什么是节点？(2')常见的节点有那三种？(3')
        //  每个元素，属性，文本都是节点   文本节点 元素节点 属性节点
        //4.说一下你对事件流的认识(5')
        // 有事件冒泡 从下到上 把addEventListener的第三个参数改为true 就成了事件捕获 有事件捕获 从上到下 事件委托 通过e或event 可以获取事件所有信息
        //5.简单描述一下事件对象(5')
        // 事件对象可以调用方法 有自己的属性 多态 继承 封装
        //二、输出类型题 25'
        //1.请写出下列输出结果，并说明原因。 5'
        function fo() {
            console.log(this.a);
        }
        var o1 = {
            a: 3,
        };
        var o2 = {
            a: 6,
        };
        var a = 9;
        o1.f = fo;
        console.log(o1);
        o2.f = o1.f;
        o1.f(); // 输出什么？ 3 o1.f = fo;将函数fo以 f:函数fo 以键值对的形式加到对象o1中 o1.f();是对象调用 所以this指向对象 找到 a: 3,得到3。
        o2.f(); // 输出什么？ 6 o2.f = o1.f; 将o1.f的属性值添加到o2为f的属性名中 f:函数fo o2.f();是对象调用 所以this指向对象 找到 a: 6,得到6。

        //2.请写出下列输出结果，并说明原因。 5'
        var F = function() {};
        Object.prototype.a = function() {
            console.log("a");
        };
        Function.prototype.b = function() {
            console.log("b");
        };
        var f = new F();
        f.a(); // a  f是函数F的实例化对象 函数F的原型上没有a方法 找到顶级对象Object的原型上有 Object.prototype.a = function() { console.log("a");}; 即打印a
        f.b(); // 报错 f是函数F的实例化对象 函数F的原型上没有a方法 找到顶级对象Object的原型上也没有 所以方法不存在会报错
        F.a(); // a   函数F即是对象 又是函数 自身没有 找到顶级对象Object的原型上有 Object.prototype.a = function() { console.log("a");}; 即打印a
        F.b(); // b   函数F即是对象 又是函数 自身没有 找到顶级函数Function的原型上有 Function.prototype.b = function() { console.log("b");}; 即打印b

        //3.请写出下列输出结果，并说明原因。 5'
        var A = function() {};
        A.prototype.n = 1;
        var b = new A();
        A.prototype = {
            n: 2,
            m: 3,
        };
        var c = new A();
        console.log(b.n); // 1 原型上有 A.prototype.n = 1; 输出1
        console.log(b.m); // undefined 原型上没有 顶级对象也没有 通过_proto_找到null 即输出undefined
        console.log(c.n); // 2 A.prototype = { n: 2,m: 3,}; 即输出2
        console.log(c.m); // 3 A.prototype = { n: 2,m: 3,}; 即输出3

        //4.请写出下列输出结果，并说明原因。 5'
        var foo = {},
            F = function() {};
        Object.prototype.a = "value a";
        Function.prototype.b = "value b";
        console.log(foo.a); // foo是个空对象 自身没有 找到顶级对象Object的原型上有Object.prototype.a = "value a"; 即输出 value a
        console.log(foo.b); // foo是个空对象 自身没有 找到顶级对象Object的原型上也没有 通过_proto_找到null 即输出undefined
        console.log(F.a); // 函数F即是对象 又是函数 自身没有 找到顶级对象Object的原型上有 Object.prototype.a = "value a";即输出 value a
        console.log(F.b); // 函数F即是对象 又是函数 自身没有 找到顶级函数Function的原型上有  Function.prototype.b = "value b"; 即输出 value b

        //5.请写出下列输出结果，并说明原因。 5'
        function A() {}

        function B(a) {
            this.a = a;
        }

        function C(a) {
            if (a) {
                this.a = a;
            }
        }
        A.prototype.a = 1;
        B.prototype.a = 1;
        C.prototype.a = 1;
        //   console.log(new A().a); // 1  原型有A.prototype.a = 1; 输出1
        //   console.log(new B().a); // undefined  需要传参 为null 因为this.a = a; 所以输出未定义
        //  console.log(new C(2).a); // 2  传参为2 if (a) {this.a = a;} 即输出2

        //三、编程题50'
        //1.在 ES5 中如何用函数模拟一个类？(请正确的给这个类添加属性和方法) 10'

        //2.使用 Promise，结合 Promise对象简单封装 AJAX 功能(涉及GET请求即可) 15'
        // function _ajaxTool(method, url, data) {
        //     return new Promise(function(resolve, reject) {
        //             let xhr = new XMLHttpRequest();
        //             if (method == "GET") {
        //                 let a = "";
        //                 for (let key in data) {
        //                     a += `${key}=${data[key]}&`;
        //                 }
        //                 let newUrl = `${url}?${a.slice(0, -1)}`;
        //                 xhr.open(method, newUrl);
        //                 xhr.send();
        //             }
        //             xhr.addEventListener("readystatechange", function() {
        //                 if (xhr.readyState == 4) {
        //                     if (xhr.status == 200) {
        //                         resolve(JSON.parse(xhr.responseText));
        //                     } else {
        //                         reject("请求失败");
        //                     }
        //                 }
        //             });
        //         }
        //     )
        // }
        //3.说说你对防抖和节流的理解，以及他们的不同 15'
        // function fd(cd, wait) {
        //     let timer;
        //     return function() {
        //         clearTimeout(timer)
        //         const zhez = this;
        //         const args = arguments;
        //         timer = setTimeout(() => {
        //             cd.apply(zhez, args)
        //         }, wait);
        //     }
        // };

        // function jl(cb, wait) {
        //     let flag = true;
        //     return function() {
        //         if (!flag) return;
        //         flag = false;
        //         let zhez = this;
        //         let args = arguments;
        //         setTimeout(() => {
        //             cb.call(zhez, args[0]);
        //             flag = true;
        //         }, wait);
        //     };
        // }
        // 防抖只获取最后的结果 节流是减少函数调用的频率
        //4.数组去重复的方法有哪些 一种4' 三种/三种以上 10'
        let arr = [1, 2, 5, 2, 4, 5, 10, 2, 5, 1, 2, 4, 5, 8, 6, 4];

        // 第一种
        // let newArr = new Set([...arr]);

        // 第二种
        // let newArr = [];
        // for (let i = 0; i < arr.length; i++) {
        //     if (newArr.indexOf(arr[i]) == -1) {
        //         newArr.push(arr[i]);
        //     }
        // }

        // 第三种
        // for (let i = 0; i < arr.length; i++) {
        //     for (let j = i + 1; j < arr.length; j++) {
        //         if (arr[i] == arr[j]) {
        //             arr.splice(j, 1);
        //             j--;
        //         }
        //     }

        // }
    </script>
</body>

</html>